import math
import os
import time
import sys

# 将工程目录加入包扫描
currPath = os.path.abspath(os.path.dirname(__file__))
srcPath = os.path.split(currPath)[0]
rootPath = os.path.split(srcPath)[0]
projectPath = os.path.split(rootPath)[0]
sys.path.append(projectPath)

from tqdm import tqdm
from src.db.CcxDataCenterDb import CcxDataCenter
from src.db.FCDB import FCDB
from src.db.ProdDb import ProdDb
from src.utils.CommonUtils import cleanScreen
from src.utils.LogUtils import Logger


class SyncNonStandardDefault:
    def __init__(self, logger: Logger, localDb: ProdDb, dataCenterDb: CcxDataCenter, fcdb: FCDB):
        self.logger = logger
        self.localDb = localDb
        self.fcdb = fcdb
        self.dataCenterDb = dataCenterDb
        self.size = 1000

    def __getOriginDataTotal__(self):
        sql = """
                SELECT count(1) as total
                FROM base_non_standard_default
                WHERE 
                    `status`=1 
                    AND new_event_type <> '商票逾期'
                    AND new_event_type is not null
            """
        r = self.dataCenterDb.QueryOne(sql)
        if r is None:
            return 0
        else:
            return r["total"]

    def __loadOriginData__(self, page, size):
        """
        小批量加载数据，分散数据库压力
        """
        sql = """
            SELECT *
            FROM base_non_standard_default
            WHERE 
                `status`=1 
                AND new_event_type <> '商票逾期'
                AND new_event_type is not null
            order by id 
            LIMIT %s, %s
        """
        return self.dataCenterDb.Query(sql, (size * page, size))

    def __loadRegionData__(self, creditCodes):
        sql = """
            SELECT cc.OUTCODE ,ci.REGION
            FROM 
            tq_comp_codecor cc 
            left join tq_comp_info ci ON cc.COMPCODE = ci.COMPCODE
            WHERE
            cc.CTYPE = 1 
            AND cc.OUTCODE IN %s
        """
        return self.fcdb.Query(sql, (creditCodes,))

    def __loadRegions__(self):
        sql = """
            SELECT `code`, `name` FROM regions
        """
        return self.dataCenterDb.Query(sql)

    def __update__(self, updateDatas):
        sql = """
            REPLACE INTO credit_base_non_standard_default
            (id, credit_code, create_time, update_time, status, 
            start_time, end_time, uuid, name, region, region_code, `level`, 
            province, province_code, city, city_code, county, county_code, 
            source, `year`, occurrence_time, public_time, `type`, content, 
            event_type, data_sources, update_user, is_platform)
            VALUES(%(id)s, %(credit_code)s, %(create_time)s, %(update_time)s, %(status)s, 
            %(start_time)s, %(end_time)s, %(uuid)s, %(name)s, %(region)s, %(region_code)s, %(level)s, 
            %(province)s, %(province_code)s, %(city)s, %(city_code)s, %(county)s, %(county_code)s, 
            %(source)s, %(year)s, %(occurrence_time)s, %(public_time)s, %(type)s, %(content)s, 
            %(event_type)s, %(data_sources)s, %(update_user)s, %(is_platform)s);
        """
        return self.localDb.ExecMany(sql, updateDatas)

    @staticmethod
    def __getRegion__(regionDataMap: dict, creditCode: str):
        if creditCode in regionDataMap.keys():
            regionCode = regionDataMap.get(creditCode)
            if regionCode.startswith("CN"):
                return regionCode[2:]
        return None

    def run(self):
        # 加载数据中心区域

        self.logger.info("加载数据中心区域")
        regions = self.__loadRegions__()
        regionsMap = {r["code"]: r["name"] for r in regions}
        self.logger.info(f"加载数据中心区域 {len(regions)} 条")

        total = self.__getOriginDataTotal__()
        self.logger.info(f"待同步数据总数：{total}")

        regionDataMap = {}

        pages = math.ceil(total / self.size)
        cnt = 0
        for page in tqdm(range(pages), desc="pages", file=sys.stdout):

            # 加载数据中心数据
            originDataList = self.__loadOriginData__(page=page, size=self.size)

            # 加载财汇企业区域
            creditCodes = list(set(d["credit_code"] for d in originDataList if d["credit_code"] not in regionDataMap.keys()))
            if len(creditCodes) > 0:
                regionDataList = self.__loadRegionData__(creditCodes)
                current = {r["OUTCODE"]: r["REGION"] for r in regionDataList}
                regionDataMap.update(current)

            # 数据封装
            for d in originDataList:
                regionCode = self.__getRegion__(regionDataMap, d["credit_code"])
                d["region"] = regionsMap[regionCode] if regionCode in regionsMap.keys() else None
                d["region_code"] = regionCode

            # 数据入库
            self.__update__(originDataList)
            cnt += len(originDataList)
        self.logger.info(f"实际同步数据 {cnt} 条")


# 主函数
def main():
    logger = Logger()
    localDb = ProdDb(logSql=False, autocommit=True)
    dataCenterDb = CcxDataCenter(logSql=False, autocommit=True)
    fcdb = FCDB(logSql=False, autocommit=True)

    cleanScreen()
    t = time.perf_counter()

    logger.info("========非标风险导入 开始 ========")

    # 同步主体名单
    sync = SyncNonStandardDefault(logger=logger, localDb=localDb, dataCenterDb=dataCenterDb, fcdb=fcdb)
    sync.run()

    cast = (time.perf_counter() - t)
    m = math.floor(cast / 60)
    s = cast - m * 60
    logger.info('总耗时: %d分%.3f秒' % (m, s))
    logger.info("========非标风险导入 结束 ========")


# 程序入口
if __name__ == "__main__":
    main()
